package com.tangyh.basic.utils.oldProject;

import com.tangyh.basic.base.AR;
import com.tangyh.basic.base.constant.StringPool;
import com.tangyh.basic.exception.BizException;
import com.tangyh.basic.utils.CommonUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.imaging.Imaging;
import org.apache.commons.imaging.common.ImageMetadata;
import org.apache.commons.imaging.formats.jpeg.JpegImageMetadata;
import org.apache.commons.imaging.formats.jpeg.exif.ExifRewriter;
import org.apache.commons.imaging.formats.tiff.TiffImageMetadata;
import org.apache.commons.imaging.formats.tiff.write.TiffOutputDirectory;
import org.apache.commons.imaging.formats.tiff.write.TiffOutputField;
import org.apache.commons.imaging.formats.tiff.write.TiffOutputSet;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.http.MediaType;
import org.springframework.http.MediaTypeFactory;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Base64;
import java.util.List;
import java.util.Optional;

/**
 * 文件工具类
 *
 * @version V1.0
 * @author: Sidon
 * @createTime: 2021-08-23 11:04
 * Copyright (C)2021-2021 福建省金柠网络科技有限公司. All rights reserved.
 */
@Slf4j
public class FileUtils {

    public static void main(String[] args) throws IOException {
//        String file = FileUtils.fileToString("C:\\Users\\28066\\Desktop\\fpmkey.txt");
//        System.out.println(file);
//    	FileUtils.deleteFile(new File("d:/11/"), false);

    }

    /**
     * 移除图片的exif信息
     *
     * @param bytes 文件字节流
     * @return
     * @throws Exception
     */
    public static byte[] removeExif(final byte[] bytes) throws Exception {
        try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
            TiffOutputSet outputSet = null;
            final ImageMetadata metadata = Imaging.getMetadata(bytes);
            if (!(metadata instanceof JpegImageMetadata)) {
                return bytes;
            }

            final JpegImageMetadata jpegMetadata = (JpegImageMetadata) metadata;
            final TiffImageMetadata exif = jpegMetadata.getExif();
            if (null != exif) {
                outputSet = exif.getOutputSet();
            }

            if (null == outputSet) {
                return bytes;
            }

            final List<TiffOutputDirectory> directories = outputSet.getDirectories();
            for (final TiffOutputDirectory directory : directories) {
                final List<TiffOutputField> fields = directory.getFields();
                for (final TiffOutputField field : fields) {
                    if (StringUtils.equalsIgnoreCase("Orientation", field.tagInfo.name)) {
                        outputSet.removeField(field.tagInfo);
                    }
                }
            }

            new ExifRewriter().updateExifMetadataLossless(bytes, os, outputSet);
            return os.toByteArray();
        }
    }

    /**
     * BufferedImage 对象转 MultipartFile
     *
     * @param bufferedImage BufferedImage 对象
     * @param fileName      文件名
     * @return
     */
    public static MultipartFile bufferedImage2MultipartFile(BufferedImage bufferedImage, String fileName) {
        String suffix = fileName.substring(fileName.lastIndexOf(StringPool.DOT) + 1);
        final byte[] bytes = bufferedImage2Byte(bufferedImage, suffix);
        return byte2MultipartFile(bytes, fileName);
    }

    /**
     * BufferedImage 转 字节
     *
     * @param bufferedImage BufferedImage 对象
     * @param fileType      文件类型
     * @return
     */
    public static byte[] bufferedImage2Byte(BufferedImage bufferedImage, String fileType) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            ImageIO.write(bufferedImage, fileType, baos);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return baos.toByteArray();
    }

    /**
     * 字节转MultipartFile
     *
     * @param bytes    文件字节
     * @param fileName 文件名，包含后缀 例: demo.pdf
     * @return
     */
    public static MultipartFile byte2MultipartFile(byte[] bytes, String fileName) {
        InputStream inputStream = new ByteArrayInputStream(bytes);
        MultipartFile file = null;
        try {
            String suffix = fileName.substring(fileName.lastIndexOf(StringPool.DOT) + 1);
            final Optional<MediaType> mediaType = MediaTypeFactory.getMediaType(fileName);
            if (mediaType.isEmpty()) {
                throw new BizException("无效的文件类型：" + suffix);
            }
            file = new MockMultipartFile(fileName, fileName, mediaType.get().toString(), inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return file;
    }

    /**
     * 删除文件
     *
     * @param file File对象
     */
    public static void deleteFile(File file) {
        if (null != file && file.exists()) {
            file.delete();
        }
    }

    /**
     * 根据路径删除文件
     *
     * @param filePath 文件路径
     */
    public static void deleteFile(String filePath) {
        if (CommonUtil.isEmpty(filePath)) {
            return;
        }
        File file = new File(filePath);
        if (file.exists()) {
            file.delete();
        }
    }


    /**
     * 获取文件真实后缀
     *
     * @param filePath 文件路径
     * @return 后缀
     */
    public static String getRealExtension(String filePath) {
        String extension = FilenameUtils.getExtension(filePath);
        try (FileInputStream fis = new FileInputStream(filePath)) {
            byte[] bs = new byte[1];
            fis.read(bs);
            String type = Integer.toHexString(bs[0] & 0xFF);
            System.out.println("----------------------------------->>>" + type);

            if (StringPool.JPG_HEX.equals(type)) {
                extension = StringPool.JPG_EXT;
            }
            if (StringPool.PNG_HEX.equals(type)) {
                extension = StringPool.PNG_EXT;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return extension;
    }


    /**
     * 获取文件真实后缀
     *
     * @param bytes 文件字节数据
     * @return 后缀
     */
    public static String getRealExtension(byte[] bytes) {
        String extension = "";
        String type = Integer.toHexString(bytes[0] & 0xFF);
        if (StringPool.JPG_HEX.equals(type)) {
            extension = StringPool.JPG_EXT;
        } else if (StringPool.PNG_HEX.equals(type)) {
            extension = StringPool.PNG_EXT;
        }
        return extension;
    }


    /*#############其他文件合并来的*/

    public static boolean uploadFile(InputStream is, String filePath) {

        boolean retCode = false;
        byte[] buffer = new byte[1024];
        FileOutputStream fos = null;

        try {
            fos = new FileOutputStream(new File(filePath));

            int n = -1;
            while ((n = is.read(buffer, 0, buffer.length)) != -1) {
                fos.write(buffer, 0, n);
            }

            retCode = true;
            log.debug("upload file success...");
        } catch (FileNotFoundException fnfe) {
            log.error("FileNotFoundException:", fnfe);
        } catch (IOException ioe) {
            log.error("IOException:", ioe);
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                    fos = null;
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (is != null) {
                try {
                    is.close();
                    is = null;
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }

        return retCode;
    }

    /**
     * 将base64字符串保存为文件
     *
     * @param fileBase64 base64字符串
     * @param filePath   保存路径文件夹
     * @param fileName   保存的文件名
     * @return
     */
    public static AR<File> uploadFile(String fileBase64, String filePath, String fileName) {

        FileOutputStream fos = null;
        try {
            File file = new File(filePath);
            if (!file.exists()) {
                file.mkdirs();
            }
            file = new File(filePath + fileName);
            fos = new FileOutputStream(file);

            byte[] by = Base64.getDecoder().decode(fileBase64);
            fos.write(by);
            fos.flush();

            log.debug("upload fileBase64 success...");
            return AR.success(file);
        } catch (FileNotFoundException fnfe) {
            log.error("FileNotFoundException:", fnfe);
        } catch (Exception oe) {
            log.error("Exception:", oe);
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return AR.fail();
    }

    /**
     * 判断图片base64字符串的文件格式
     *
     * @param base64ImgData
     * @return
     */
    public static String checkImageBase64Format(String base64ImgData) {
        byte[] b = Base64.getDecoder().decode(base64ImgData);
        String type = "";
        if (0x424D == ((b[0] & 0xff) << 8 | (b[1] & 0xff))) {
            type = "bmp";
        } else if (0x8950 == ((b[0] & 0xff) << 8 | (b[1] & 0xff))) {
            type = "png";
        } else if (0xFFD8 == ((b[0] & 0xff) << 8 | (b[1] & 0xff))) {
            type = "jpg";
        }
        return type;
    }

    /**
     * 将byte[]保存为文件
     *
     * @param by
     * @param filePath 保存路径文件夹
     * @param fileName 保存的文件名
     * @return
     */
    public static boolean uploadFile(byte[] by, String filePath, String fileName) {

        boolean retCode = false;
        FileOutputStream fos = null;

        try {
            File file = new File(filePath);
            if (!file.exists()) {
                file.mkdirs();
            }
            file = new File(filePath + fileName);
            fos = new FileOutputStream(file);

            fos.write(by);
            fos.flush();

            retCode = true;
            log.debug("upload byte[] success...");
        } catch (FileNotFoundException fnfe) {
            log.error("FileNotFoundException:", fnfe);
        } catch (Exception oe) {
            log.error("Exception:", oe);
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                    fos = null;
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return retCode;
    }

    /**
     * 将文件转成base64字符串
     *
     * @param filePath 文件路径
     * @return
     */
    public static String fileToString(String filePath) {
        FileInputStream fos = null;
        try {
            File file = new File(filePath);
            fos = new FileInputStream(file);
            byte[] buffer = new byte[fos.available()];
            fos.read(buffer);
            String by = Base64.getEncoder().encodeToString(buffer);
            log.debug("get fileBase64 success...");
            return by;
        } catch (FileNotFoundException fnfe) {
            log.error("FileNotFoundException:", fnfe);
        } catch (Exception oe) {
            log.error("Exception:", oe);
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return null;
    }

    /**
     * 将文件转成byte[]
     *
     * @param filePath 文件路径
     * @return
     */
    public static byte[] fileToByte(String filePath) {
        FileInputStream fos = null;
        try {
            File file = new File(filePath);
            fos = new FileInputStream(file);
            byte[] buffer = new byte[fos.available()];
            fos.read(buffer);
            log.debug("get fileBase64 success...");
            return buffer;
        } catch (FileNotFoundException fnfe) {
            log.error("FileNotFoundException:", fnfe);
        } catch (Exception oe) {
            log.error("Exception:", oe);
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                    fos = null;
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return null;
    }


    public static String getFileContent(File f, String code) {

        BufferedReader reader = null;
        FileInputStream fis = null;
        InputStreamReader fr = null;
        StringBuilder fileContent = new StringBuilder();
        try {
            fis = new FileInputStream(f);
            fr = new InputStreamReader(fis, code);
            reader = new BufferedReader(fr);
            String line = "";
            while ((line = reader.readLine()) != null) {
                fileContent.append(line.trim());
            }

        } catch (Exception e) {
            log.error("Exception:", e);
            return null;
        } finally {
            try {
                if (reader != null) {
                    reader.close();
                    reader = null;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (fr != null) {
                try {
                    fr.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                fr = null;
            }
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                fis = null;
            }
        }
        return fileContent.toString();
    }

    public static String getFileContent(byte[] by, String code) {

        BufferedReader reader = null;
        ByteArrayInputStream fis = null;
        InputStreamReader fr = null;
        StringBuilder fileContent = new StringBuilder();
        try {
            fis = new ByteArrayInputStream(by);
            fr = new InputStreamReader(fis, code);
            reader = new BufferedReader(fr);
            String line = "";
            while ((line = reader.readLine()) != null) {
                fileContent.append(line.trim());
            }

        } catch (Exception e) {
            log.error("Exception:", e);
            return null;
        } finally {
            try {
                if (reader != null) {
                    reader.close();
                    reader = null;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (fr != null) {
                try {
                    fr.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                fr = null;
            }
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                fis = null;
            }
        }
        return fileContent.toString();
    }


    public static boolean setFileContent(String path, String content) {
        boolean flag = false;
        DataOutputStream dos = null;
        FileOutputStream fos = null;
        try {
            if (content != null && content.length() >= 0) {
                byte abyte[] = content.getBytes();
                fos = new FileOutputStream(path);
                dos = new DataOutputStream(fos);
                dos.write(abyte, 0, abyte.length);
                dos.flush();

                flag = true;
            }
        } catch (FileNotFoundException e) {
            log.error("FileNotFoundException:" + e);
        } catch (IOException e) {
            log.error("IOException" + e);
        } finally {
            if (dos != null) {
                try {
                    dos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                dos = null;
            }
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                fos = null;
            }
        }
        return flag;
    }


    public static String getFileExt(String fileName) {
        if (fileName == null) return "";

        String ext = "";
        int lastIndex = fileName.lastIndexOf(".");
        if (lastIndex >= 0) {
            ext = fileName.substring(lastIndex + 1).toLowerCase();
        }

        return ext;
    }

    /**
     * 删除目录下的所有文件
     *
     * @param file
     * @param flag true删除本目录文件夹  false不删除本目录文件夹
     * @return
     */
    public static boolean deleteFile(File file, boolean flag) {
        if (!file.exists()) {
            return false;
        }
        File[] files = file.listFiles();
        for (File f : files) {
            if (f.isDirectory()) {
                deleteFile(f, true);
            } else {
                f.delete();
            }
        }
        if (flag) {
            file.delete();
        }
        return true;
    }

    public static void deleteList(List<String> list) {
        for (String s : list) {
            File file = new File(s);
            if (file.exists()) {
                file.delete();
            }
        }
    }
}
